package pers.hl.module_main.main

import android.Manifest
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.NotificationUtils
import com.blankj.utilcode.util.TimeUtils
import com.permissionx.guolindev.PermissionX
import pers.hl.common.base.BaseVBVMFragment
import pers.hl.common.base.IFragment
import pers.hl.common.base.ext.showMessage
import pers.hl.lib_global.common.AMapLocateHelper
import pers.hl.lib_global.common.Const
import pers.hl.lib_global.common.MMKVHelper
import pers.hl.module_main.R
import pers.hl.module_main.bookshelf.BookShelfFragment
import pers.hl.module_main.broadcastreceiver.NotificationReceiver
import pers.hl.module_main.common.AuthHelper
import pers.hl.module_main.databinding.FragmentMainBinding
import pers.hl.module_main.explore.ExploreFragment
import pers.hl.module_main.mine.*
import java.util.*

class MainFragment : BaseVBVMFragment<FragmentMainBinding, MineViewModel>() {


    private lateinit var viewPagerAdapter: MainViewPagerAdapter
    private lateinit var fragments: List<Fragment>

    override fun initView(savedInstanceState: Bundle?) {
        registerBroadcast()
        requestPermission()
        initFragments()
        addViewPagerEvents()
        addBottomNavEvents()
        addBarEvents()
    }

    /**
     * 动态注册通知点击广播，并加入生命周期
     */
    private fun registerBroadcast() {
        val notificationReceiver = NotificationReceiver()
        val intentFilter = IntentFilter()
        intentFilter.addAction(Const.NotificationKeys.KEY_EXPIRING_BORROWS)
        mContext.registerReceiver(notificationReceiver, intentFilter)
        lifecycle.addObserver(object : DefaultLifecycleObserver {

            override fun onCreate(owner: LifecycleOwner) {
                super.onCreate(owner)
                mContext.registerReceiver(notificationReceiver, intentFilter)
            }

            override fun onDestroy(owner: LifecycleOwner) {
                super.onDestroy(owner)
                mContext.unregisterReceiver(notificationReceiver)
            }
        })
    }

    /**
     * 申请权限
     */
    @SuppressLint("CheckResult")
    private fun requestPermission() {
        val permissions = listOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
        PermissionX.init(this)
            .permissions(permissions)
            .onExplainRequestReason { scope, deniedList ->
                val message = "PermissionX需要您同意以下权限才能正常使用"
                scope.showRequestReasonDialog(deniedList, message, "确定", "取消")
            }
            .request { allGranted, grantedList, deniedList ->
                if (allGranted) {
                    // todo 权限申请成功
                    LogUtils.d("权限申请成功")
                } else {
                    showMessage("您拒绝了如下权限：$deniedList, 将无法正常使用app部分功能")
                }
            }
    }


    private fun initFragments() {
        val exploreFragment = ExploreFragment()
        val bookShelfFragment = BookShelfFragment()
        val mineFragment = MineFragment()
        fragments = listOf(exploreFragment, bookShelfFragment, mineFragment)
    }

    private fun addViewPagerEvents() {
        viewPagerAdapter = MainViewPagerAdapter(requireActivity(), fragments)
        mBinding.viewPager.apply {
            adapter = viewPagerAdapter
            registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {

                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                    val fragment: Fragment = fragments[position]
                    if (fragment is IFragment) {
                        setBarTitle(fragment.name())
                    }
                    setBottomNavigationPosition(position)
                    showTopBar(position != 2)
                }
            })
        }
    }

    private fun setBottomNavigationPosition(position: Int) {
        mBinding.bottomNav.apply {
            selectedItemId = menu.getItem(position).itemId
        }
    }

    private fun addBottomNavEvents() {
        mBinding.bottomNav.setOnNavigationItemSelectedListener { item ->
            when (item.itemId) {
                R.id.nav_home -> {
                    setViewPagerPosition(0)
                    setBarRightIcon(R.drawable.ic_search)
                    return@setOnNavigationItemSelectedListener true
                }
                R.id.nav_book_shelf -> {
                    setViewPagerPosition(1)
                    setBarRightIcon(R.drawable.ic_add)
                    return@setOnNavigationItemSelectedListener true
                }
                R.id.nav_personal -> {
                    setViewPagerPosition(2)
                    setBarRightIcon(R.drawable.ic_qr_scan)
                    return@setOnNavigationItemSelectedListener true
                }
            }
            return@setOnNavigationItemSelectedListener false
        }
    }

    private fun setBarRightIcon(resId: Int) {
        mBinding.appbar.ivBarRight.setImageResource(resId)
    }

    private fun setViewPagerPosition(position: Int) {
        mBinding.viewPager.currentItem = position
    }

    private fun setBarTitle(name: String) {
        mBinding.appbar.toolbar.apply {
            title = name
        }
    }

    /**
     * 添加标题栏图标点击监听事件
     */
    private fun addBarEvents() {
        mBinding.appbar.ivBarRight.setOnClickListener {
            val curFragment = viewPagerAdapter.createFragment(mBinding.viewPager.currentItem)
            if (curFragment is OnBarIconClickListener) {
                curFragment.onTitleBarIconClick()
            }
        }
    }


    override fun initData(savedInstanceState: Bundle?) {
//        val user = MMKV.defaultMMKV()?.decodeParcelable(Const.KEY.USER, User::class.java)
//        LogUtils.dTag(TAG + "user", user)
        AuthHelper.verifyToken()
        initCurLocation()
        initMyCollection()
        checkGlobalNotifications();
    }

    /**
     * 检查全局通知
     */
    private fun checkGlobalNotifications() {
        checkBorrowExpired()
    }

    /**
     * 检查即将到期的借阅并提醒
     */
    private fun checkBorrowExpired() {
        // 先检查今天是否点击过，若点击过则不进行检查
        if (checkIfClickedNotificationToday(Const.NotificationKeys.KEY_EXPIRING_BORROWS)) {
            return
        }
        mViewModel.checkExpiringRecord().observe(this, Observer {
            if (it.isEmpty()) {
                return@Observer
            }
            NotificationUtils.notify(
                Const.NotificationKeys.KEY_EXPIRING_BORROWS,
                Const.NotificationKeys.ID_EXPIRING_BORROWS
            ) { builder ->
                builder?.apply {
//                    val intent = Intent(this@MainFragment.mContext, NotificationReceiver::class.java)
                    val intent = Intent(Const.NotificationKeys.KEY_EXPIRING_BORROWS)
                    val broadcastIntent = PendingIntent.getBroadcast(
                        this@MainFragment.mContext,
                        0,
                        intent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                    )
                    builder.setContentIntent(broadcastIntent)
                    setSmallIcon(R.drawable.ic_library)
                    setAutoCancel(true)
                    setContentTitle("您有借阅即将到期")
                    setContentInfo("您有${it.size}条借阅已逾期或即将到期，点击查看")
                    setContentText("您有${it.size}条借阅已逾期或即将到期，点击查看")
                }
            }
        })
    }

    /**
     * 检查今天是否点击过该类型的通知，点击过则不再展示
     * 取出缓存的通知点击行为，以日期匹配
     * @param notificationType 通知类型
     */
    private fun checkIfClickedNotificationToday(notificationType: String): Boolean {
        val map = MMKVHelper.getNotificationClickAction() ?: return false
        val date = map[notificationType]
        val nowDate = TimeUtils.date2String(Date(), Const.DateFormat.FORMAT_YYYY_MM_DD)
        if (TextUtils.equals(date, nowDate)) {
            return true
        }
        return false
    }

    private fun initMyCollection() {
        mViewModel.fetchMyCollect().observe(this, Observer {
            if (it.isNullOrEmpty()) {
                return@Observer
            }
            val collectIds = mutableSetOf<String>()
            it.forEach { data ->
                if (data.collectId == null) {
                    return@Observer
                }
                collectIds.add(data.bookId.toString())
            }
            LogUtils.d("保存我的收藏书籍id:$collectIds")
            MMKVHelper.saveCollection(collectIds)
        })
    }

    private fun initCurLocation() {
        LogUtils.d("开始定位")
        AMapLocateHelper.getLocation {
            LogUtils.d("保存定位信息：$it")
            MMKVHelper.saveCurLocation(it)
        }
    }

    fun showTopBar(show: Boolean) {
        mBinding.appbar.toolbar.visibility = if (show) View.VISIBLE else View.GONE
    }

    /**
     * 标题栏图标点击监听事件
     */
    interface OnBarIconClickListener {
        fun onTitleBarIconClick()
    }

}